﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;

using Newtonsoft.Json.Linq;

using eBook.Core;
using eBook.Core.BusinessObjects;
using eBook.Core.Contracts;

namespace eBook.Services
{
  public class LibraryThingBookLookup : IBookLookup
  {

    private CookieContainer _cookieJar = new CookieContainer();

    // http://librarything.com
    // userid=tolgak key=1147231893
    public boBookInfo GetBookInfoByISBN(ISBN isbn)
    {
      boBookInfo info = new boBookInfo { InfoProvider = "MASH" };
      List<string> links = new List<string>();
      List<string> bookauthors = new List<string>();
      List<string> topics = new List<string>();

      JObject jo = this.GetJsonData(isbn);
      string joRoot = string.Format("ISBN:{0}", isbn.StrippedISBN);

      JArray publishers = (JArray) jo[joRoot]["publishers"];
      info.PublisherName = (string) publishers[0].SelectToken("name");

      JObject identifiers = (JObject) jo[joRoot]["identifiers"];
      info.LCCN = (string) identifiers["lccn"][0];
      info.ISBN10 = (string) identifiers["isbn_10"][0];
      


      JObject classifications = (JObject)jo[joRoot]["classifications"];
      info.DeweyDecimal = (string)((JArray)classifications["dewey_decimal_class"])[0];

      JObject cover = (JObject)jo[joRoot]["cover"];
      info.SmallImageURL  = (string) cover["small"];
      info.MediumImageURL = (string) cover["medium"];
      info.LargeImageURL  = (string) cover["large"];

      info.Title = (string)jo[joRoot]["title"];
      info.NumberOfPages = jo[joRoot]["number_of_pages"].ToString();


      JArray authors = (JArray) jo[joRoot]["authors"];
      foreach (var x in authors)
        bookauthors.Add( (string) x["name"] );
      info.Authors = bookauthors.ToArray();


      JArray subjects = (JArray) jo[joRoot]["subjects"];
      foreach (var x in subjects)
        topics.Add((string) x["name"]);
      info.Topics = topics.ToArray();
      

      string olUrl = (string)jo[joRoot]["url"];      
      links.Add(string.Format("OpenLibrary link | {0}", olUrl));
      links.Add(string.Format("LC permalink | http://lccn.loc.gov/{0}", info.LCCN));

      string libraryThingId = (string)identifiers["librarything"][0];
      links.Add(string.Format("LibraryThing link | http://www.librarything.com/work/{0}", libraryThingId));

      string gutenberg = (string)identifiers["project_gutenberg"][0];
      if ( !string.IsNullOrEmpty(gutenberg) )
        links.Add(string.Format("Project Gutenberg link | http://www.gutenberg.org/ebooks/{0}", gutenberg));

      info.Links = links.ToArray();


      return info;
    }


    private JObject GetJsonData(ISBN isbn)
    {
      string url = string.Format("http://openlibrary.org/api/books?format=json&jscmd=data&bibkeys=ISBN:{0}", isbn.StrippedISBN);
      string page = GetHtml(url);
      return JObject.Parse(page);
    }

    public string GetHtml(string url)
    {
      HttpWebRequest request = PrepareHttpGetRequest(url);
      HttpWebResponse response = (HttpWebResponse)request.GetResponse();

      using (Stream stream = response.GetResponseStream())
      {
        string html = string.Empty;
        StreamReader reader = new StreamReader(stream, Encoding.UTF8);
        try
        {
          html = reader.ReadToEnd();         
        }
        finally
        {
          reader.Close();
        }
        return html;
      }
    }

    public HttpWebRequest PrepareHttpGetRequest(string url)
    {
      HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
      httpRequest.CookieContainer = _cookieJar;

      httpRequest.AllowAutoRedirect = true;
      httpRequest.MaximumAutomaticRedirections = 4;
      httpRequest.Method = "GET";
      httpRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

      httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:5.0) Gecko/20100101 Firefox/5.0";
      httpRequest.ContentType = "text/html;charset=UTF-8";
      httpRequest.Timeout = 10000;

      return httpRequest;
    }





  }



}

